#include <SD.h>
#include <SPI.h>
#include <M5GFX.h>
#include <M5Unified.h>
#include <cJSON.h>
#include <M5UnitGLASS2.h>


#define SD_SPI_SCK_PIN  36
#define SD_SPI_MISO_PIN 35
#define SD_SPI_MOSI_PIN 37
#define SD_SPI_CS_PIN   4

M5UnitGLASS2 glass(2, 1);


void setup(void) {
    M5.begin();
    // SD Card Initialization
    SPI.begin(SD_SPI_SCK_PIN, SD_SPI_MISO_PIN, SD_SPI_MOSI_PIN, SD_SPI_CS_PIN);

    if (!SD.begin(SD_SPI_CS_PIN, SPI, 25000000)) {
        // Print a message if the SD card initialization
        // fails orif the SD card does not exist.
        // 如果SD卡初始化失败或者SD卡不存在，则打印消息.
        while (1)
            ;
    }

    M5.Display.drawJpgFile(SD, "/1.jpg", 40, 0);
    // M5.Lcd.drawJpgFile(SD, "/p1.jpg", 20, 30, 40, 50);
    // M5.Lcd.drawJpgFile(fs::FS &fs, const char *path, uint16_t x, uint16_t y,
    // uint16_t maxWidth, uint16_t maxHeight, uint16_t offX, uint16_t offY,
    // jpeg_div_t scale);
    M5.Display.setTextSize(2);
    M5.Display.setFont(&fonts::efontCN_12);
    M5.Display.print("屏幕启动OK！");
    Serial.setRxBufferSize(2048);
    Serial.begin(115200);
    Serial.println("\n\n{\"s\":\"boot\"}");


    glass.init();
    glass.setFont(&fonts::efontCN_12);
    glass.setTextSize(1);
    glass.print("PocketBuddy");
}


char serialLineBuf[2048];
#define FLAG_CLEAR (1)
#define FLAG_FILL_BOX (2)
#define FLAG_OLED (4)
void loop() {
    M5GFX* gfx = &M5.Display;
    if (Serial.available()) {
        int len = Serial.readBytesUntil('\n', serialLineBuf, sizeof(serialLineBuf)-1);
        serialLineBuf[len] = 0;

        cJSON *root = cJSON_Parse(serialLineBuf);
        if (root == NULL) {
            Serial.println("{\"s\":\"json parse error\"}");
            Serial.println(serialLineBuf);
            return;
        }

        // Get command parameters with default values
        cJSON *item;
        int flag = 0, x = 0, y = 0, w = 0, h = 0, fg = 65535, bg = 0;
        
        if ((item = cJSON_GetObjectItem(root, "f"))) {
            flag = item->valueint;
        }
        if ((item = cJSON_GetObjectItem(root, "x"))) {
            x = item->valueint;
        }
        if ((item = cJSON_GetObjectItem(root, "y"))) {
            y = item->valueint;
        }
        if ((item = cJSON_GetObjectItem(root, "w"))) {
            w = item->valueint;
        }
        if ((item = cJSON_GetObjectItem(root, "h"))) {
            h = item->valueint;
        }
        if ((item = cJSON_GetObjectItem(root, "fg"))) {
            fg = item->valueint;
        }
        if ((item = cJSON_GetObjectItem(root, "bg"))) {
            bg = item->valueint;
        }
        if (flag & FLAG_OLED){
            gfx = &glass;
        }
        if (flag & FLAG_CLEAR){
            gfx->clear(bg);
        }
        if (flag & FLAG_FILL_BOX){
            gfx->fillRect(x, y, w, h, fg);
        }
        
        cJSON *textItem = cJSON_GetObjectItem(root, "text");
        if (textItem != NULL) {
            gfx->setTextColor(fg, bg);
            gfx->setCursor(x, y);
            gfx->print(textItem->valuestring);
        }
        
        cJSON *imageItem = cJSON_GetObjectItem(root, "image");
        if (imageItem != NULL) {
            gfx->drawJpgFile(SD, imageItem->valuestring, x, y);
        }
        // Clean up
        cJSON_Delete(root);
        //Serial.println("{\"s\":\"ok\"}");
    }
}